package com.ngis.model.mdl;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class ModelClass {
	public ModelClass() {
		mName = "Model Name";
		mUID = "";
		mExecutionStyle = EExecutionStyle.EES_SIMPLE_CALCULATION;

		mModelAttribute = new ModelAttribute();
		mModelBehavior = new ModelBehavior();
		mModelRuntime = new ModelRuntime();
	}

	public void setName(String pName) {
		mName = pName;
	}

	public String getName() {
		return mName;
	}

	public void setUID(String pUID) {
		mUID = pUID;
	}

	public String getUID() {
		return mUID;
	}

	public void setExecutionStyle(EExecutionStyle pStyle) {
		mExecutionStyle = pStyle;
	}

	public EExecutionStyle getExecutionStyle() {
		return mExecutionStyle;
	}

	public ModelAttribute getModelAttribute() {
		return mModelAttribute;
	}

	public ModelBehavior getModelBehavior() {
		return mModelBehavior;
	}

	public ModelRuntime getModelRuntime() {
		return mModelRuntime;
	}

	public boolean LoadFromXmlFile(String fileName) {
		SAXReader reader = new SAXReader();
		Document doc;
		try {
			doc = reader.read(new File(fileName));

			Element modelClassEle = doc.getRootElement();

			mName = modelClassEle.attributeValue("name");
			mUID = modelClassEle.attributeValue("uid");
			String styleStr = "";
			if (modelClassEle.attribute("style") != null)
				styleStr = modelClassEle.attributeValue("style");
			else if (modelClassEle.attribute("type") != null)
				styleStr = modelClassEle.attributeValue("type");

			
			if (styleStr.equals("SimpleCalculation")) {
				mExecutionStyle = EExecutionStyle.EES_SIMPLE_CALCULATION;
			} else if (styleStr.equals("TimeSeries")) {
				mExecutionStyle = EExecutionStyle.EES_TIME_SERIES;
			} else {
				mExecutionStyle = EExecutionStyle.EES_STATE_SIMULATION;
			}

			mModelAttribute.loadFromXml(modelClassEle);
			mModelBehavior.loadFromXml(modelClassEle);
			mModelRuntime.loadFromXml(modelClassEle);

			return true;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

			return false;
		}
	}

	public boolean FormatToXmlFile(String fileName) {
		Document doc = DocumentHelper.createDocument();
		Element modelClassEle = doc.addElement("ModelClass");
		modelClassEle.addAttribute("name", mName);
		modelClassEle.addAttribute("uid", mUID);
		if (mExecutionStyle == EExecutionStyle.EES_SIMPLE_CALCULATION)
			modelClassEle.addAttribute("style", "SimpleCalculation");
		else if (mExecutionStyle == EExecutionStyle.EES_TIME_SERIES)
			modelClassEle.addAttribute("style", "TimeSeries");
		else
			modelClassEle.addAttribute("style", "StateSimulation");

		mModelAttribute.formatToXml(modelClassEle);
		mModelBehavior.formatToXml(modelClassEle);
		mModelRuntime.formatToXml(modelClassEle);

		try {
			XMLWriter writer;
			writer = new XMLWriter(new FileWriter(fileName));
			writer.write(doc);
			writer.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}

	public boolean LoadFromXmlStream(String xmlStr) {
		Document doc = null;
		try {
			doc = DocumentHelper.parseText(xmlStr);
			Element modelClassEle = doc.getRootElement();
			mName = modelClassEle.attributeValue("name");
			mUID = modelClassEle.attributeValue("uid");
			String styleStr = modelClassEle.attributeValue("style");
			if (styleStr == null){
				styleStr = modelClassEle.attributeValue("type");
			}
			if (styleStr == null){
				mExecutionStyle = EExecutionStyle.EES_SIMPLE_CALCULATION;
			}else if (styleStr.equals("SimpleCalculation")) {
				mExecutionStyle = EExecutionStyle.EES_SIMPLE_CALCULATION;
			} else if (styleStr.equals("TimeSeries")) {
				mExecutionStyle = EExecutionStyle.EES_TIME_SERIES;
			} else {
				mExecutionStyle = EExecutionStyle.EES_STATE_SIMULATION;
			}

			mModelAttribute.loadFromXml(modelClassEle);
			mModelBehavior.loadFromXml(modelClassEle);
			mModelRuntime.loadFromXml(modelClassEle);

			return true;
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	public String FormatToXmlStream() {
		Document doc = DocumentHelper.createDocument();
		Element modelClassEle = doc.addElement("ModelClass");
		modelClassEle.addAttribute("name", mName);
		modelClassEle.addAttribute("uid", mUID);
		if (mExecutionStyle == EExecutionStyle.EES_SIMPLE_CALCULATION)
			modelClassEle.addAttribute("style", "SimpleCalculation");
		else if (mExecutionStyle == EExecutionStyle.EES_TIME_SERIES)
			modelClassEle.addAttribute("style", "TimeSeries");
		else
			modelClassEle.addAttribute("style", "StateSimulation");

		mModelAttribute.formatToXml(modelClassEle);
		mModelBehavior.formatToXml(modelClassEle);
		mModelRuntime.formatToXml(modelClassEle);

		String xmlStr = doc.asXML();
		return xmlStr;
	}

	public boolean compareOther(ModelClass pClass, boolean withRuntime, CompareFlag compareFlag) {
		boolean flag = false;
		if (mModelAttribute != null) {
			flag = mModelAttribute.compareOther(pClass.getModelAttribute(), compareFlag);
			if (flag == false)
				return false;
		}
		if (mModelBehavior != null) {
			flag = mModelBehavior.compareOther(pClass.getModelBehavior(), compareFlag);
			if (flag == false)
				return false;
		}
		if (withRuntime != false && mModelRuntime != null) {
			flag = mModelRuntime.compareOther(pClass.getModelRuntime(), compareFlag);
			if (flag == false)
				return false;
		}
		return true;
	}

	private String mName;
	private String mUID;
	private EExecutionStyle mExecutionStyle;

	private ModelAttribute mModelAttribute;
	private ModelBehavior mModelBehavior;
	private ModelRuntime mModelRuntime;
}
